package com.ytd.smartcanteen.weighting

import android.annotation.SuppressLint
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.os.SystemClock
import android.provider.Settings
import android.text.TextUtils
import android.view.Gravity
import android.view.KeyEvent
import android.view.View
import android.widget.PopupWindow
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import cn.hutool.crypto.SmUtil
import cn.ytd.smartcanteen.weighting.BuildConfig
import cn.ytd.smartcanteen.weighting.R
import cn.ytd.smartcanteen.weighting.databinding.ActivityMainBinding
import com.ytd.common.base.BaseActivity
import com.ytd.common.base.BaseApplication
import com.ytd.common.bean.BaseRequest
import com.ytd.common.bean.BaseResponse
import com.ytd.common.constant.ApiConstants
import com.ytd.common.dialog.NormalDialog
import com.ytd.common.dialog.ProgressDialog
import com.ytd.common.dialog.ResultDialog
import com.ytd.common.net.NetCallBack
import com.ytd.common.net.PushObserve
import com.ytd.common.net.RequestManager
import com.ytd.common.net.SocketManager
import com.ytd.common.util.FormatUtil
import com.ytd.common.util.LocalDataManager
import com.ytd.common.util.LogUtil
import com.ytd.common.util.NetUtil
import com.ytd.common.util.ThreadUtil
import com.ytd.common.util.ToastUtil
import com.ytd.common.util.YtdConfig
import com.ytd.smartcanteen.weighting.bean.MealInfo
import com.ytd.smartcanteen.weighting.bean.request.SyncRequestData
import com.ytd.smartcanteen.weighting.bean.response.GetConsumeResponse
import com.ytd.smartcanteen.weighting.bean.response.LoginResponse
import com.ytd.smartcanteen.weighting.bean.response.SyncResponse
import com.ytd.smartcanteen.weighting.constants.Constants
import com.ytd.smartcanteen.weighting.devices.LEDManager
import com.ytd.smartcanteen.weighting.devices.ScaleManager
import com.ytd.smartcanteen.weighting.devices.ScannerManager
import com.ytd.smartcanteen.weighting.dialog.BindDialog
import com.ytd.smartcanteen.weighting.dialog.LoginDialog
import com.ytd.smartcanteen.weighting.dialog.PortDialog
import com.ytd.smartcanteen.weighting.dialog.ScaleDialog
import com.ytd.smartcanteen.weighting.dialog.SetDialog
import com.ytd.smartcanteen.weighting.dialog.SetDishDialog
import com.ytd.smartcanteen.weighting.fragment.ConsumeFragment
import com.ytd.smartcanteen.weighting.fragment.NormalFragment
import com.ytd.smartcanteen.weighting.receiver.ClearReceiver
import com.ytd.smartcanteen.weighting.util.ConsumeNetUtil
import com.ytd.smartcanteen.weighting.util.ConsumeWarnUtil
import com.ytd.smartcanteen.weighting.util.FoodManager
import com.ytd.smartcanteen.weighting.util.MealInfoUtil
import com.ytd.smartcanteen.weighting.util.RequestUtil
import com.ytd.smartcanteen.weighting.util.ShutdownUtil
import com.ytd.smartcanteen.weighting.util.WeightConfig
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.math.BigDecimal
import java.util.Date


class MainActivity : BaseActivity(), PushObserve, FoodManager.FoodChangeCallBack,
    ScannerManager.ScannerCallBack,
    ScaleManager.ScaleCallBack {

    private val uploadAddWeight: Double = 0.2
    private val offlineState: Int = 698
    private val msgCheckNext: Int = 699
    private val msgShowTime: Int = 999
    private var isNetSettingWait: Boolean = false
    private var versionClickCount = 0
    val msgHideSystemUi = 1679
    val msgVersionClick = 678
    val msgInit = 1680
    val msgInitFood = 1683
    val msgConfig = 1681
    val msgLocalOrder = 1688
    val msgHideSystemUiDelayed = 5000L
    private val msgInitDelayed = 10000L
    val msgOfflineStateDelayed = 20000L

    var isAnomaly: Boolean = false
    private var isSettingConfig: Boolean = false
    private var tmpWeight: BigDecimal = BigDecimal.ZERO

    private var isFirst = true

    private val mHandler: Handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            when (msg.what) {
                msgHideSystemUi -> {
                    hideSystemUI()
                    sendEmptyMessageDelayed(msgHideSystemUi, msgHideSystemUiDelayed)
                }

                msgInit -> {
                    if (settingPopupWindow?.isShowing == true) {
                        if (settingPopupWindow is BindDialog) {
                            return
                        }
                        settingPopupWindow?.dismiss()
                    }
                    showBindingDialog()
                }

                msgVersionClick -> {
                    versionClickCount = 0
                }

                msgCheckNext -> {
                    checkNext()
                }

                offlineState -> {
                    sendEmptyMessageDelayed(msgCheckNext, msgOfflineStateDelayed)
                    sendEmptyMessageDelayed(offlineState, msgOfflineStateDelayed)
                }

                msgConfig -> {
                    handleConfigTimeOut()
                }

                msgInitFood -> {
                    FoodManager.getInstance().initData()
                }

                msgShowTime -> {
                    binding.tvTime.text = FormatUtil.getShowDateFormat()
                    sendEmptyMessageDelayed(msgShowTime, 1000)
                }

                msgLocalOrder -> {
                    post(localOrder)
                }

                else -> {}
            }
        }
    }

    private val showTypeNormal = 0
    private val showTypeConsume = 1
    private var showType = -1
    private lateinit var binding: ActivityMainBinding
    private lateinit var clearReceiver: ClearReceiver
    private lateinit var progressDialog: ProgressDialog
    private var mealInfo: MealInfo? = null
    private var settingPopupWindow: PopupWindow? = null
    private var networkDialog: NormalDialog? = null
    private var resultDialog: ResultDialog? = null
    private var errorDialog: ResultDialog? = null
    private var offlineDialog: NormalDialog? = null

    private val normalFragment: NormalFragment = NormalFragment()
    private val consumeFragment: ConsumeFragment = ConsumeFragment()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        LogUtil.d(this@MainActivity.javaClass.simpleName + "   onCreate")
        EventBus.getDefault().register(this)
        addFragment(consumeFragment, "consume", true)
        addFragment(normalFragment, "open", false)
        showFragment(showTypeNormal)
        hideSystemUI()
        initData()
        mHandler.sendEmptyMessageDelayed(msgHideSystemUi, msgHideSystemUiDelayed)
    }

    @SuppressLint("SetTextI18n")
    private fun initData() {
        progressDialog = ProgressDialog(this)
        binding.tvVersion.text = "V${BuildConfig.VERSION_NAME}"
        binding.tvVersion.setOnClickListener {
            if (showType != showTypeNormal) {
                return@setOnClickListener
            }
            mHandler.removeMessages(msgVersionClick)
            versionClickCount++
            if (versionClickCount == 5) {
                versionClickCount = 0
                settingPopupWindow = LoginDialog(this@MainActivity)
                (settingPopupWindow as LoginDialog).Show(
                    Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0
                ) //设置layout在PopupWindow中显示的位置
            }
            mHandler.sendEmptyMessageDelayed(msgVersionClick, msgInitDelayed)
        }
        binding.viewRight.setOnLongClickListener {
            if (showType == showTypeNormal) {
                settingPopupWindow = ScaleDialog(this@MainActivity)
                (settingPopupWindow as ScaleDialog).show(
                    Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0
                )
                return@setOnLongClickListener false
            } else {
                return@setOnLongClickListener false
            }
        }
        mHandler.sendEmptyMessage(msgShowTime)
        isDebug()
        initReceiver()
        initDevice()
        initNet()
    }

    private fun isDebug() {
        if (!BuildConfig.DEBUG) {
            return
        }
        binding.tvDeviceName.setOnClickListener {

        }
        binding.tvDeviceName.setOnLongClickListener {
            val localhostStr = cn.hutool.core.net.NetUtil.getLocalhostStr()
            ToastUtil.showToast(localhostStr)
            return@setOnLongClickListener true
        }
        binding.tvOnlineStatus.setOnClickListener {
        }
        binding.tvMerchantName.setOnClickListener {
        }
        binding.tvMerchantName.setOnLongClickListener {
            return@setOnLongClickListener true
        }
    }

    private fun initNet() {
        offline()

        RequestManager.getInstance().setPushObserve(this)
        FoodManager.getInstance().init(this)
        if (checkInitAndNetWork()) {
            return
        }
        if (!YtdConfig.isDeviceActivate()) {
            mHandler.sendEmptyMessageDelayed(msgInit, 1000)
        } else {
            SocketManager.getInstance().initSocket()
        }
        isNetSettingWait = false
    }

    @SuppressLint("ClickableViewAccessibility")
    fun showBindingDialog() {
        settingPopupWindow = BindDialog(this@MainActivity)
        settingPopupWindow?.isTouchable = true
        settingPopupWindow?.isFocusable = true
        settingPopupWindow?.isOutsideTouchable = false
        settingPopupWindow?.setTouchInterceptor { _, event ->
            event.y < 70
        }
        (settingPopupWindow as BindDialog).Show(Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0)
    }

    private fun checkInitAndNetWork(): Boolean {
        if (!YtdConfig.isDeviceActivate() && !NetUtil.isNetworkAvailable(this)) {
            showNetWorkDialog()
            return true
        }
        return false
    }

    private fun showNetWorkDialog() {
        if (networkDialog == null) {
            networkDialog = NormalDialog(this, false)
            networkDialog?.setCallBack(object : NormalDialog.CallBack {
                override fun dismiss() {}
                override fun onClickOk() {
                    val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
                    this@MainActivity.startActivity(intent)
                    isNetSettingWait = true
                }
            })
        }
        networkDialog?.show()
    }

    private fun initDevice() {
        LEDManager.getInstance().init()
        LEDManager.getInstance().closeAll()
        LogUtil.d("LEDManager closeAll initDevice")
        ScannerManager.getInstance().init()
        ScannerManager.getInstance().setCallback(this)
        ScaleManager.getInstance().init()
        ScaleManager.getInstance().setCallback(this)
    }

    @SuppressLint("UnspecifiedRegisterReceiverFlag")
    private fun initReceiver() {
        clearReceiver = ClearReceiver(this)
        val filter = IntentFilter()
        filter.addAction("com.win.action.WIN_BROADCAST")
        registerReceiver(clearReceiver, filter)
    }

    private var initDialog: ResultDialog? = null
    override fun onResume() {
        super.onResume()
        LogUtil.d(this@MainActivity.javaClass.simpleName + "    onResume")
        if (!YtdConfig.initBaseKey()) {
            initDialog = ResultDialog(
                this,
                getString(R.string.read_init_key_fail),
                com.ytd.common.R.mipmap.lib_icon_fail,
                0,
                true
            )
            initDialog?.show()
            checkBaseKey()
        } else {
            if (initDialog != null && initDialog?.isShowing == true) {
                initDialog?.dismiss()
            }
        }
        if (isNetSettingWait) {
            isNetSettingWait = false
            if (!checkInitAndNetWork()) {
                initNet()
            }
        }
    }

    override fun onPause() {
        super.onPause()
        executeCheckBaseKey = false
    }

    private var executeCheckBaseKey = true
    private fun checkBaseKey() {
        if (executeCheckBaseKey) {
            return
        }
        executeCheckBaseKey = true
        ThreadUtil.execute {
            while (executeCheckBaseKey) {
                SystemClock.sleep(1000)
                if (YtdConfig.initBaseKey()) {
                    runOnUiThread {
                        if (initDialog != null && initDialog?.isShowing == true) {
                            initDialog?.dismiss()
                        }
                    }
                    executeCheckBaseKey = false
                    LogUtil.d("checkBaseKey dismiss")
                }
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        LogUtil.d("onDestroy")
        unregisterReceiver(clearReceiver)
        EventBus.getDefault().unregister(this)
        MealInfoUtil.release()
        LEDManager.getInstance().release()
        ScaleManager.getInstance().release()
        ScannerManager.getInstance().release()
        FoodManager.getInstance().release()
        SocketManager.getInstance().closeSocket()
    }

    fun setIsAnomaly(isAnomaly: Boolean) {
        this.isAnomaly = isAnomaly
        LEDManager.getInstance().setAnomaly(isAnomaly)
        LEDManager.getInstance().setCloseFlicker(true)
        LEDManager.getInstance().closeAll()
        ScannerManager.getInstance().resetData()
        ConsumeWarnUtil.resetData()
        LogUtil.d("LEDManager closeAll setIsAnomaly $isAnomaly")
        if (errorDialog?.isShowing == true) {
            errorDialog?.dismiss()
        }
        hideWarnDialog()
        refreshLed()
    }

    private fun fragmentRefreshUi() {
        consumeFragment.refreshUi()
        normalFragment.refreshUi()
    }

    private fun hideSystemUI() {
        // Enables regular immersive mode.
        // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
        // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        val decorView = window.decorView
        decorView.systemUiVisibility =
            (View.SYSTEM_UI_FLAG_IMMERSIVE // Set the content to appear under the system bars so that the
                    // content doesn't resize when the system bars hide and show.
                    or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // Hide the nav bar and status bar
                    or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN)
    }

    private fun showFragment(type: Int) {
        if (showType == type) {
            return
        }
        val ft = supportFragmentManager.beginTransaction()
        ft.hide(normalFragment)
        ft.hide(consumeFragment)
        when (type) {
            showTypeNormal -> ft.show(normalFragment)
            showTypeConsume -> ft.show(consumeFragment)
        }
        ft.commitAllowingStateLoss()
        showType = type
    }

    private fun addFragment(fragment: Fragment, name: String, hide: Boolean) {
        val ft = supportFragmentManager.beginTransaction()
        if (fragment.isAdded) {
            return
        }
        ft.add(R.id.fl_content, fragment, name)
        if (hide) {
            ft.hide(fragment)
        }
        ft.setTransition(FragmentTransaction.TRANSIT_NONE)
        ft.commitAllowingStateLoss()
    }

    fun saveConfig(isReconnection: Boolean) {
        val text: String = if (!YtdConfig.isDeviceActivate()) {
            SocketManager.getInstance().initSocket()
            getString(R.string.text_activating)
        } else {
            isSettingConfig = true
            SocketManager.getInstance().resetSocket(isReconnection)
            getString(R.string.text_configuring)
        }
        showResDialog(text, R.mipmap.icon_config, 10, false)
        mHandler.sendEmptyMessageDelayed(msgConfig, msgInitDelayed)
    }

    private fun handleConfigTimeOut() {
        hideProgressDialog()
        showResDialog(
            getString(R.string.text_failed_server_not_responding),
            R.mipmap.icon_config,
            2,
            false
        )
        showBindingDialog()
    }

    private fun showProgressDialog(cancelable: Boolean) {
        progressDialog.setCanceledOnTouchOutside(cancelable)
        progressDialog.setCancelable(cancelable)
        progressDialog.show()
    }

    fun showProgressDialog(text: String, cancelable: Boolean) {
        progressDialog.setText(text)
        showProgressDialog(cancelable)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun handleEvent(event: BaseResponse?) {
        when (event?.interfaceName) {
            ApiConstants.DEVICE_ACTIVATE, ApiConstants.DEVICE_CONFIG -> {
                mHandler.removeMessages(msgInit)
                mHandler.removeMessages(msgConfig)
                processActivate(event)
            }

            ApiConstants.GET_DEVICE_DETAIL -> {
                mHandler.removeMessages(msgInit)
                processDeviceDetail(event)
            }

            ApiConstants.HEART_BEAT -> {
                heartBeat(event)
            }

            ApiConstants.OFFLINE -> {
                offline()
            }

            Constants.GET_FOOD_PAGE_END -> {
                processGetFoodPageEnd()
            }

            ApiConstants.MSG_SERVER_ERROR -> {
                hideProgressDialog()
            }

            ApiConstants.CODE_SERVER_ERROR -> {
                mHandler.removeMessages(msgConfig)
                hideProgressDialog()
                showResDialog(
                    if (TextUtils.isEmpty(event.msg)) {
                        getString(com.ytd.common.R.string.text_server_error)
                    } else {
                        event.msg
                    }, R.mipmap.icon_warn, 3, false
                )
            }

            Constants.NO_BINDING_ERROR -> {
                showResDialog(
                    getString(R.string.text_unbound_dishes),
                    R.mipmap.icon_warn,
                    0,
                    false
                )
                normalFragment.setFoodInfo(null)
            }

            ApiConstants.GET_CURRENT_TIME -> {
                syncData()
            }

            else -> {}
        }
    }

    private fun syncData() {
        val baseRequest = BaseRequest()
        baseRequest.interfaceName = Constants.GET_DATA_UPDATE_STATUS
        val data = SyncRequestData()
        data.updateTime = FormatUtil.getDateFormat(Date(WeightConfig.getSyncTime()))
        baseRequest.data = data
        RequestManager.getInstance().request(baseRequest, object : NetCallBack<SyncResponse> {
            override fun onSuccess(result: SyncResponse?) {
                if (result?.updated == true) {
                    FoodManager.getInstance().initFoodData()
                }
            }

            override fun onFail(code: Int, msg: String?) {

            }
        })
    }

    private fun hideProgressDialog() {
        runOnUiThread {
            if (progressDialog.isShowing) {
                progressDialog.dismiss()
            }
        }
    }

    private fun processGetFoodPageEnd() {
        progressDialog.setText(getString(R.string.text_sync_completed))
        mHandler.postDelayed({ hideProgressDialog() }, 1000)
        runOnUiThread {
            if (settingPopupWindow is LoginDialog) {
                (settingPopupWindow as LoginDialog).restart()
            }
        }
    }

    private fun offline() {
        if (!isFirst && BaseApplication.getInstance().isOffline) {
            return
        }
        hideProgressDialog()
        mHandler.sendEmptyMessage(offlineState)
        BaseApplication.getInstance().isOffline = true
        LogUtil.e("设备离线：" + YtdConfig.getOfflineMode())
        binding.tvOnlineStatus.text = getString(R.string.text_offline)
        binding.czView.setBackgroundResource(R.drawable.offline_state_roundview)
        LogUtil.d("LEDManager showOffline offline")
        if (!YtdConfig.getOfflineMode()) {
            showOfflineDialog()
        } else {
            BaseApplication.getInstance().isOfflineWait = false
            FoodManager.getInstance().getFoodInfo()
        }
        refreshLed()
        isFirst = false
    }

    private fun showOfflineDialog() {
        LogUtil.e("offline", "showOfflineDialog")
        if (offlineDialog == null) {
            offlineDialog = NormalDialog(this, false)
            offlineDialog?.setText(getString(R.string.text_whether_to_enter_offline_mode))
            offlineDialog?.setBtnText(getString(R.string.text_enter), getString(R.string.text_wait))
            offlineDialog?.setCallBack(object : NormalDialog.CallBack {
                override fun dismiss() {
                    BaseApplication.getInstance().isOfflineWait = true
                    showOfflineWaitDialog()
                }

                override fun onClickOk() {
                    BaseApplication.getInstance().isOfflineWait = false
                    FoodManager.getInstance().getFoodInfo()
                }
            })
        }
        offlineDialog?.show()
    }

    private fun showOfflineWaitDialog() {
        LogUtil.e("设备离线重连中")
        progressDialog.setText(getString(R.string.text_offline_reconnection_in_progress))
        if (!progressDialog.isShowing) {
            showProgressDialog(false)
        }
    }

    private fun heartBeat(event: BaseResponse) {
        if (event.isSuccess) {
            mHandler.sendEmptyMessage(msgCheckNext)
            mHandler.removeMessages(offlineState)
            setOnline()
        }
    }

    private fun checkNext() {
        ShutdownUtil.setDeviceOff()
        ShutdownUtil.setDeviceOn()

        val nowMealTimeString = FormatUtil.getNowMealTimeString()
        if (mealInfo?.mealEndTime.equals(nowMealTimeString)) {
            FoodManager.getInstance().getFoodInfo()
        } else {
            for (mealInfo in FoodManager.getInstance().currentBindingMealList) {
                if (mealInfo.mealStartTime == nowMealTimeString) {
                    FoodManager.getInstance().getFoodInfo()
                    return
                }
            }
        }
        if (mealInfo?.inMeal == false) { //增加未开餐检测节点
            if (this.mealInfo != null) {
                FoodManager.getInstance().checkMeal(mealInfo!!)
            }
        }
    }

    private fun setOnline() {
        if (!isFirst && !BaseApplication.getInstance().isOffline) {
            return
        }
        if (offlineDialog != null && offlineDialog?.isShowing == true) {
            offlineDialog?.dismiss()
        }
        LogUtil.e("设备恢复在线")
        BaseApplication.getInstance().isOffline = false
        if (BaseApplication.getInstance().isOfflineWait) {
            BaseApplication.getInstance().isOfflineWait = false
            hideProgressDialog()
        }
        binding.tvOnlineStatus.text = getString(R.string.text_online)
        binding.czView.setBackgroundResource(R.drawable.online_state_roundview)
        LEDManager.getInstance().closeAll()
        refreshLed()
        LogUtil.d("LEDManager closeAll setOnline")
        if (!isFirst) {
            FoodManager.getInstance().initBindFood()
        }
        isFirst = false
    }

    private fun processDeviceDetail(event: BaseResponse) {
        FoodManager.getInstance().initData()
        hideProgressDialog()
        if (event.isSuccess) {
            changUI()
        }
        if (!YtdConfig.getMerchantId().equals(WeightConfig.getLocalMerchantId())) {
            LogUtil.d("商户切换，重新下载数据")
            WeightConfig.setLocalMerchantId(YtdConfig.getMerchantId())
            FoodManager.getInstance().initFoodData()
        }
    }

    private fun processActivate(event: BaseResponse) {
        hideProgressDialog()
        if (event.isSuccess) {
            if (settingPopupWindow?.isShowing == true) {
                settingPopupWindow?.dismiss()
            }
            progressDialog.setText(getString(com.ytd.common.R.string.base_downloading_data))
            progressDialog.show()
            if (event.interfaceName == ApiConstants.DEVICE_ACTIVATE) {
                showResDialog(
                    getString(R.string.text_activation_successful),
                    R.mipmap.icon_config,
                    2,
                    false
                )
                YtdConfig.setDeviceActivate(true)
                mHandler.sendEmptyMessageDelayed(
                    msgInitFood, msgHideSystemUiDelayed
                )//系统配置信息返回后，有可能重启socket造成数据丢失，所以延时更新数据
            } else {
                if (isSettingConfig) {
                    showResDialog(
                        getString(R.string.text_successfully_configured),
                        R.mipmap.icon_config,
                        2,
                        false
                    )
                }
            }
            isSettingConfig = false
            SocketManager.getInstance().synchronizationData()
            binding.tvMerchantName.text = YtdConfig.getMerchantName()
        } else {
            if (settingPopupWindow?.isShowing == true) {
                settingPopupWindow?.dismiss()
            }
            showBindingDialog()
            showResDialog(event.msg, R.mipmap.icon_config, 2, false)
        }
    }

    override fun onPush(response: BaseResponse?) {
        when (response?.code) {
            ApiConstants.PUSH_UPDATE_DEVICE -> {
                runOnUiThread {
                    changUI()
                    processDeviceDetail(response)
                }
                RequestManager.getInstance().msgReceiveProcess(response, "推送：修改设备成功")
            }

            Constants.PUSH_UPDATE_FOOD_CATEGORY -> {
                val updateFoodCategory = FoodManager.getInstance().updateFoodCategory(response)
                RequestManager.getInstance().msgReceiveProcess(response, "推送：修改餐品分类成功")
                runOnUiThread {
                    if (settingPopupWindow is SetDishDialog) {
                        (settingPopupWindow as SetDishDialog).updateFoodCategory(updateFoodCategory)
                    }
                }
            }

            Constants.PUSH_SET_FOOD_INFO -> {
                FoodManager.getInstance().setFoodInfo(response)
                RequestManager.getInstance()
                    .msgReceiveProcess(response, "推送：设置设备绑定餐品成功")
                runOnUiThread {
                    if (settingPopupWindow is SetDishDialog) {
                        (settingPopupWindow as SetDishDialog).updateBindFood()
                    }
                }
            }

            Constants.PUSH_SET_FOOD_INFO_LIST -> {
                FoodManager.getInstance().setFoodInfoList(response)
                RequestManager.getInstance()
                    .msgReceiveProcess(response, "推送：设置设备全部绑定餐品成功")
                runOnUiThread {
                    if (settingPopupWindow is SetDishDialog) {
                        (settingPopupWindow as SetDishDialog).updateBindFood()
                    }
                }
            }

            Constants.PUSH_UPDATE_FOOD -> {
                val updateFood = FoodManager.getInstance().updateFood(response)
                RequestManager.getInstance().msgReceiveProcess(response, "推送：修改餐品成功")
                runOnUiThread {
                    if (settingPopupWindow is SetDishDialog) {
                        (settingPopupWindow as SetDishDialog).updateFood(updateFood)
                    }
                }
            }

            Constants.PUSH_UPDATE_MEAL_TIME -> {
                val updateMealTime = FoodManager.getInstance().updateMealTime(response)
                RequestManager.getInstance().msgReceiveProcess(response, "推送：修改餐别成功")
                mHandler.postDelayed(
                    {
                        if (settingPopupWindow is SetDishDialog) {
                            (settingPopupWindow as SetDishDialog).updateMealTime()
                        }
                    }, if (updateMealTime) {
                        100
                    } else {
                        1500
                    }
                )
            }

            Constants.PUSH_APPLY_UPLOAD_OFFLINE_ORDER -> {
                LocalDataManager.getInstance().uploadNow()
                RequestManager.getInstance()
                    .msgReceiveProcess(response, "推送：请求上传离线消费订单处理成功")
            }

            else -> {

            }
        }
    }

    @SuppressLint("SetTextI18n")
    private fun changUI() {
        binding.tvDeviceName.text = String.format(
            getString(R.string.text_device_location),
            YtdConfig.getRow(),
            YtdConfig.getColumn()
        ) + " " + YtdConfig.getPosNo()
        binding.tvMerchantName.text = YtdConfig.getMerchantName()
    }

    override fun onMealChange(mealInfo: MealInfo?) {
        LogUtil.d("Activity onMealChange")
        runOnUiThread {
            this.mealInfo = mealInfo
            normalFragment.setFoodInfo(mealInfo)
            if (mealInfo != null) {
                hideUnboundDishesDialog()
            }
        }
    }

    private fun hideUnboundDishesDialog() {
        if (resultDialog?.isShowing == true && resultDialog?.text.equals(getString(R.string.text_unbound_dishes))) {
            resultDialog?.dismiss()
        }
    }

    private var onConsume = false

    /**
     * 扫码器回调
     */
    override fun onScanner(data: String?) {
        if (isSetting()) {
            LogUtil.d("onScanner isSetting")
            return
        }
        LogUtil.d("onScanner：$data")
        if (mealInfo == null) {
            showResDialog(getString(R.string.text_unbound_dishes), R.mipmap.icon_warn, 0, false)
            return
        }
        if (mealInfo?.inMeal == false && !YtdConfig.getConsumeNonBusinessEnabled()) {
            showResDialog(getString(R.string.text_unserved_time), R.mipmap.icon_warn, 0, false)
            return
        }
        onConsume = true
        mHandler.post { consumeFragment.updateMealInfoAndRefreshUi(mealInfo) }
        if (BaseApplication.getInstance().isLocalMode) {
            startLocalOrder(data, false)
            return
        }
        localOrder.data = data
        localOrder.time = FormatUtil.getLogTimeFormat(Date())
        mHandler.sendEmptyMessageDelayed(msgLocalOrder, 500)
        getConsume(data)
    }

    private fun getConsume(data: String?) {
        val consume = RequestUtil.getConsume(data)
        RequestManager.getInstance().request(consume, object : NetCallBack<GetConsumeResponse> {
            override fun onSuccess(result: GetConsumeResponse?) {
                mHandler.removeMessages(msgLocalOrder)
                if (!onConsume) {
                    return
                }
                consumeFragment.setConsume(false, false, data, result)
                showFragment(showTypeConsume)
                hideWarnDialog()
            }

            override fun onFail(code: Int, msg: String?) {
                mHandler.removeMessages(msgLocalOrder)
                if (!onConsume) {
                    return
                }
                showFragment(showTypeNormal)
                LogUtil.d("LEDManager showRed getConsume onFail")
                showResDialog(msg, R.mipmap.icon_warn, 0, false)
                LEDManager.getInstance().showRed()
            }
        })
    }

    private val localOrder = object : Runnable {
        var data: String? = ""
        var time: String? = ""
        override fun run() {
            LogUtil.d("getConsume timeout $time")
            if (!onConsume) {
                return
            }
            LogUtil.d("getConsume timeout startLocalOrder")
            startLocalOrder(data, true)
        }
    }

    fun closeAnomaly() {
        if (!isAnomaly) {
            return
        }
        this.isAnomaly = false
        ConsumeWarnUtil.isErrorEvent = false
        LEDManager.getInstance().setAnomaly(isAnomaly)
        LEDManager.getInstance().setCloseFlicker(true)
        LEDManager.getInstance().closeAll()
        LogUtil.d("LEDManager closeAll closeAnomaly")
        if (errorDialog?.isShowing == true) {
            errorDialog?.dismiss()
        }
        hideWarnDialog()
        refreshLed()
    }

    private fun startLocalOrder(data: String?, timeout: Boolean) {
        runOnUiThread {
            val result = GetConsumeResponse()
            result.accountNo = "$data"
            result.balance = 0.0
            result.totalConsume = 0.0
            result.newUser = false
            if (mealInfo != null) {
                result.whetherLimitWeightOfTake = mealInfo?.whetherLimitWeightOfTake!!
                result.limitWeightOfTake = mealInfo?.limitWeightOfTake!!
                result.startingWeight = mealInfo?.startingWeight!!
            }
            consumeFragment.setConsume(true, timeout, data, result)
            showFragment(showTypeConsume)
            hideWarnDialog()
        }
    }

    /**
     * 扫码器没扫描到东西
     */
    override fun onClose() {
        if (isSetting()) {
            LogUtil.d("onClose isSetting")
            return
        }
        onConsume = false
        LogUtil.d("onScanner onClose")
        if (mealInfo == null) {
            return
        }
        hideWarnDialog()
        if (BaseApplication.getInstance().isLocalMode) {
            LogUtil.d("LEDManager onClose showOffline")
            LEDManager.getInstance().showOffline()
        } else {
            LogUtil.d("LEDManager onClose closeAll")
            LEDManager.getInstance().closeAll()
        }
        showFragment(showTypeNormal)
    }

    /**
     * 秤稳定下的重量
     */
    override fun onStable(decimal: BigDecimal?) {
        LogUtil.d("Scale onStable: " + decimal?.toDouble())
        consumeFragment.onScaleStable(decimal)
        onDialogChange(decimal)
        if (decimal != null) {
            updateTmpWeight(decimal)
        }
    }

    private fun updateTmpWeight(decimal: BigDecimal) {
        if (showType != showTypeNormal) {
            return
        }
        val subtract = decimal.subtract(tmpWeight)
        if (subtract.toDouble() > uploadAddWeight) {
            ConsumeNetUtil.uploadFoodWeight()
        }
        tmpWeight = decimal
    }

    /**
     * 秤的实时重量
     */
    override fun onChange(decimal: BigDecimal?) {
        LogUtil.d("Scale onChange: " + decimal?.toDouble())
        consumeFragment.onScaleChange(decimal)
        onDialogChange(decimal)
    }

    private fun onDialogChange(decimal: BigDecimal?) {
        runOnUiThread {
            if (settingPopupWindow is ScaleDialog) {
                (settingPopupWindow as ScaleDialog).onScaleChange(decimal)
            }
        }
    }

    fun showErrorDialog(msg: String, res: Int) {
        if (resultDialog?.isShowing == true) {
            resultDialog?.dismiss()
        } else {
            if (isSetting()) {
                LogUtil.d("showErrorDialog isSetting")
                return
            }
        }

        LogUtil.d("showErrorDialog: $msg ")
        runOnUiThread {
            isAnomaly = true
            LogUtil.d("LEDManager showRed showErrorDialog $msg")
            LEDManager.getInstance().showRed()
            LEDManager.getInstance().setAnomaly(true)
            if (errorDialog?.isShowing == true) {
                return@runOnUiThread
            }
            errorDialog = ResultDialog(this, msg, res, 0, true)
            errorDialog?.show()
        }
    }

    fun showResDialog(res: String?, ivRes: Int, timeout: Int, isDis: Boolean) {
        LogUtil.d("showResDialog: $res  倒计时：$timeout ")
        runOnUiThread {
            if (resultDialog?.isShowing == true && resultDialog?.text == res) {
                resultDialog?.resetTime()
                return@runOnUiThread
            }
            if (resultDialog?.isShowing == true) {
                resultDialog?.setOnDismissListener(null)
                resultDialog?.dismiss()
            }
            resultDialog = ResultDialog(this@MainActivity, res, ivRes, timeout, isDis)
            if (!isDis) {
                resultDialog?.setOnDismissListener {
                    LEDManager.getInstance().stopWarning()
                    LogUtil.d("LEDManager setOnDismissListener")
                    mHandler.postDelayed({ refreshLed() }, 10L)
                }
            }
            resultDialog?.show()
        }
    }

    fun showOverweightDialog() {
        runOnUiThread {
            if (resultDialog?.isShowing == true && resultDialog?.text == getString(R.string.text_do_not_weigh_the_scale)) {
                resultDialog?.resetTime()
                return@runOnUiThread
            }
            showResDialog(
                getString(R.string.text_do_not_weigh_the_scale),
                R.mipmap.icon_warn,
                0,
                false
            )
            LEDManager.getInstance().showRed()
            LogUtil.d("LEDManager showRed showOverweightDialog")
        }
    }

    fun getResultDialog(): ResultDialog? {
        return resultDialog
    }

    fun login(password: String) {
        if (BaseApplication.getInstance().isLocalMode) {
            if (SmUtil.sm3(password) == YtdConfig.getMerchantPwd()) {
                showSettingDialog()
            } else {
                showResDialog(getString(R.string.text_password_error), R.mipmap.icon_warn, 2, false)
            }
        } else {
            RequestManager.getInstance()
                .request(RequestUtil.getLogin(password), object : NetCallBack<LoginResponse> {
                    override fun onSuccess(result: LoginResponse?) {
                        YtdConfig.setToken(result?.token)
                        setIsAnomaly(false)
                        showSettingDialog()
                    }

                    override fun onFail(code: Int, msg: String?) {
                        showResDialog(msg, R.mipmap.icon_warn, 2, false)
                    }
                })
        }
    }

    private fun showSettingDialog() {
        settingPopupWindow = SetDialog(this@MainActivity)
        (settingPopupWindow as SetDialog).Show(
            Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0
        ) //设置layout在PopupWindow中显示的位置
    }

    fun showSetDishDialog() {
        settingPopupWindow = SetDishDialog(this@MainActivity)
        (settingPopupWindow as SetDishDialog).Show(
            Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0
        ) //设置layout在PopupWindow中显示的位置
    }

    fun setTitle(txt: String?) {
        binding.tvMerchantName.text = txt
    }

    override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        if (hasFocus) {
            changUI()
        }
        if (!YtdConfig.isDeviceActivate()) {
            mHandler.sendEmptyMessageDelayed(msgInit, 1000)
        }
        LogUtil.d("onWindowFocusChanged:$hasFocus")
    }

    fun showPortDialog() {
        settingPopupWindow = PortDialog(this@MainActivity)
        (settingPopupWindow as PortDialog).show(
            Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0
        ) //设置layout在PopupWindow中显示的位置
    }

    fun hideWarnDialog() {
        if (resultDialog?.isShowing == true) {
            resultDialog?.dismiss()
        }
    }

    fun showLimitDialog(intValue: Int) {
        ThreadUtil.executeMainDelayed({
            runOnUiThread {
                val res = getString(R.string.text_exceeded, intValue)
                var showRes = ""
                if (resultDialog != null) {
                    showRes = resultDialog!!.text
                }
                if (resultDialog?.isShowing == true && showRes.contains(getString(R.string.text_exceeded_split))) {
                    resultDialog?.text = res
                    return@runOnUiThread
                }
                showResDialog(res, R.mipmap.icon_warn, 0, false)
                LEDManager.getInstance().showRed()
                LogUtil.d("LEDManager showRed showLimitDialog")
            }
        }, 100)
    }

    fun isSetting(): Boolean {
        return settingCount != 0
    }

    private var settingCount = 0

    fun settingShow() {
        settingCount++
        LEDManager.getInstance().showViolet()
    }

    fun settingDismiss() {
        settingCount--
        if (settingCount > 0) {
            LEDManager.getInstance().showViolet()
            setTitle(getString(com.ytd.common.R.string.base_dialog_btn_setting))
        } else {
            ConsumeWarnUtil.resetData()
            LEDManager.getInstance().closeAll()
            refreshLed()
        }
    }

    private fun refreshLed() {
        if (BaseApplication.getInstance().isLocalMode) {
            LogUtil.d("LEDManager refreshLed showOffline")
            LEDManager.getInstance().showOffline()
        }
        fragmentRefreshUi()
        if (settingCount > 0) {
            LEDManager.getInstance().showViolet()
        }
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        return keyCode == KeyEvent.KEYCODE_BACK && !isSetting()
    }
}